package checkers3d.logic;

import checkers3d.presentation.IRenderResource;
import java.awt.Point;
import java.util.LinkedList;

/**
 *
 * @author Ruben Acuna
 * @author Brenton Dong
 * @author Leila Malekian
 */
public class BoardObjectChecker implements IBoardObjectDynamic
{
    private Player owner;

    //for IDrawable
    private Point drawPosition;
    private IRenderResource resource;

    private final int SETUP_ROWS = 3;

    //constructor passing in player and icon
    public BoardObjectChecker(Player player, IRenderResource icon)
    {
        setOwner(player);
        setDrawPosition(new Point());
        setRenderResource(icon);
    }

    public void setOwner (Player player)
    {
            owner = player;
    }

    public Player getOwner()
    {
            return owner;
    }

    //returns true when a piece is occupying a square
    public boolean IsBlocking()
    {
            return true;
    }

    //determines whether a player can move a piece
    public boolean isSelectableBy(Player player)
    {
        if (player == this.getOwner())
            return true;
        else
            return false;
    }

    //everything is visible at this point in the build
    public boolean isVisibleTo(Object player)
    {
            return true;
    }

    //stores location of each move
    public LinkedList<Point3D> getPath(Point3D relativePosition)
    {
        LinkedList<Point3D> path = new LinkedList();

        if(relativePosition.x == 1 && relativePosition.y == 1)
        {
            //path complete, do nothing.
        }
        else if(relativePosition.x == 2 && relativePosition.y == 2)
        {
            path.add(new Point3D(1,1,relativePosition.z));
        }
        else if(relativePosition.x == -1 && relativePosition.y == 1)
        {
            //path complete, do nothing.
        }
        else if(relativePosition.x == -2 && relativePosition.y == 2)
        {
            path.add(new Point3D(-1,1,relativePosition.z));
        }
        else if(relativePosition.x == 0 && relativePosition.y == 0 && relativePosition.z == 1){
            //path complete, do nothing.
        }
        else if(relativePosition.x == 0 && relativePosition.y == 0 && relativePosition.z == -1){
            //path compelte, do nothing.
        }
        
        //add last step
        path.add(new Point3D(relativePosition.x, relativePosition.y, relativePosition.z));

        return path;
    }

    public boolean isValidMoveTarget(PlayingSurface3D playingSurface, Point3D position, Point3D target)
    {
        if(!UtilBoardObject.isPositionBlocked(playingSurface.getPosition(target)))
        {
            // single step up left
            if (position.x-target.x == 1 && position.y-target.y == 1 && position.z==target.z)
                return true;
            // single step up right
            else if (position.x-target.x == -1 && position.y-target.y == 1 && position.z==target.z)
                return true;
        }

        return false;
    }

    public boolean isValidWarpTarget(PlayingSurface3D playingSurface, Point3D position, Point3D target)
    {
        if(!UtilBoardObject.isPositionBlocked(playingSurface.getPosition(target)))
        {
            // warp up
            if (position.x-target.x == 0 && position.y-target.y == 0 && position.z-target.z == 1)
                return true;
            // warp down
            else if (position.x-target.x == 0 && position.y-target.y == 0 && position.z-target.z == -1)
                return true;
        }

        return false;
    }

    public boolean isValidJumpTarget(PlayingSurface3D playingSurface, Point3D position, Point3D target){
        if(!UtilBoardObject.isPositionBlocked(playingSurface.getPosition(target)))
        {
            // jump step up left
            if (position.x-target.x == 2 && position.y-target.y == 2 && position.z==target.z){
                Point3D midPoint = new Point3D(position.x-1,position.y-1,position.z);
                if(playingSurface.getPositionDynamicObject(midPoint)!=null && playingSurface.getPositionDynamicObject(position)!=null)
                    if(playingSurface.getPositionDynamicObject(midPoint).getOwner() != playingSurface.getPositionDynamicObject(position).getOwner())
                        return true;
            }
            // jump step up right
            else if (position.x-target.x == -2 && position.y-target.y == 2 && position.z==target.z){
                Point3D midPoint = new Point3D(position.x+1,position.y-1,position.z);
                if(playingSurface.getPositionDynamicObject(midPoint)!=null && playingSurface.getPositionDynamicObject(position)!=null)
                    if(playingSurface.getPositionDynamicObject(midPoint).getOwner() != playingSurface.getPositionDynamicObject(position).getOwner())
                        return true;
            }
        }

        return false;
    }

    public boolean isValidSetupPosition(PlayingSurface3D playingSurface3D, Point3D location)
    {
        boolean valid = false;
        
        if(!UtilBoardObject.isPositionBlocked(playingSurface3D.getPosition(location)))
            if(location.y >= (playingSurface3D.getSizeY() - SETUP_ROWS))
                valid = true;

        return valid;
    }

    public BoardObjectTouchEffect onTouch(IBoardObject other)
    {
        if (getOwner() != other.getOwner() && (other instanceof BoardObjectChecker || other instanceof BoardObjectKing))
            //removes piece if it's not the owner's piece
            return BoardObjectTouchEffect.REMOVE;
        else
            //doesn't allow for the capture of your own piece
            return BoardObjectTouchEffect.NOTHING;
    }

    public int getSetupCount(int boardSizeX, int boardSizeY, int boardSizeZ)
    {
        //FIXME: we always use boardSizeX here, is that wrong?
        //FIXME: the number of boards is not taken into account.
       int setupCount = (int)((boardSizeX - 8) * 2.5 + 10);

       return setupCount;
    }

    public boolean isBlocking()
    {
        return true;
    }

    /**
     * Returns a new instance of this object type with all local variables the
     * same.
     *
     * @return A new instance of this object.
     * @see IBoardObject
     */    
    @Override
    public IBoardObject clone()
    {
        return new BoardObjectChecker(getOwner(), getRenderResource());
    }

    //START - STUFF FROM IDRAWABLE
    public Point getDrawPosition()
    {
        return drawPosition;
    }

    public void setDrawPosition(Point position)
    {
        drawPosition = position;
    }

    public IRenderResource getRenderResource()
    {
        return resource;
    }

    public void setRenderResource(IRenderResource resource)
    {
        this.resource = resource;
    }

    public String getDataAsString()
    {
        return ("Checker\t" + owner.getDataAsString());
    }

    @Override
    public String toString()
    {
        return getClass().getSimpleName() + " - owner: " + getOwner().getName();
    }
    //END - STUFF FROM IDRAWABLE
}

